package com.jsj.controller;

import java.io.*;
import java.util.List;
import javax.servlet.http.HttpServletResponse;


import com.jsj.domain.FileMessageVO;
import com.jsj.domain.TopFile;
import com.jsj.seafile.ServiceImpl;
import com.jsj.service.ITopFileService;
import com.jsj.utils.HammingUtil;
import com.jsj.utils.WordUtil;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;

import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import static com.ruoyi.common.utils.PageUtils.startPage;

/**
 * 文件查重Controller
 *
 * @author timec
 * @date 2022-08-21
 */
@RestController
@RequestMapping("/simhash/topFile")
public class TopFileController extends BaseController {

    @Autowired
    private ITopFileService topFileService;

    @Autowired
    private ISysUserService userService;
    /**
     * SimHash查重
     */
    @PostMapping("/check2")
    public AjaxResult checkFile(MultipartFile file,TopFile qdTopFile) throws Exception {
        // 查重标志=班级id+0+测验id+0+题目id
        String checkmark = qdTopFile.getClassid().toString() + "0" + qdTopFile.getSubtopid().toString() + "0" + qdTopFile.getProblemid().toString();
        try {
            // 获取文件simhash值
            String msgSimHash = WordUtil.getSimHash(file);
            // 查询所属分组的所有文件SimHash值
            TopFile topFile = new TopFile();
            topFile.setCheckmark(checkmark);
            List<TopFile> list = topFileService.selectTopFileList(topFile);
            //最大相似度
            double similarity = 0;
            for (TopFile tF : list) {
                if (similarity < HammingUtil.getSimilarity(msgSimHash, tF.getSimhash())) {
                    similarity = HammingUtil.getSimilarity(msgSimHash, tF.getSimhash());
                }
            }
            // 相似度处理
            similarity = (double) Math.round(similarity * 10000) / 100;
            // 查重信息
            String code = "";// 20220为通过，20221为未通过。
            String msg = "";
            if (similarity > 70) {
                code = "20221";
                msg = "未通过查重，相似度为：" + similarity + "%,大于70%";
            } else {
                code = "20220";
                msg = "恭喜你，已通过查重，相似度为：" + similarity + "%,小于70%";
                // 本地保存文件
                String group = "/" + qdTopFile.getClassid().toString() + "/" + qdTopFile.getSubtopid().toString() + "/" + qdTopFile.getProblemid().toString();

                ServiceImpl seaFile = new ServiceImpl();
                String fileName = file.getOriginalFilename();
                String prfix = fileName.substring(fileName.lastIndexOf("."));
                // 重命名=学号+姓名
                SysUser sysUser = userService.selectUserById(qdTopFile.getUserid());
                fileName = sysUser.getUserName() + sysUser.getNickName() + prfix;
                // 文件，重命名，分组文件夹
                // 判断新建文件夹
                WordUtil.newSeaFile(qdTopFile);
                //   /1/1/1/
                WordUtil.saveSeaFile(file, fileName, group);

                // 保存文件
                // WordUtil.saveFile(file, group);
                // 文件信息存入数据库
                TopFile bcTopFile = new TopFile();
                bcTopFile.setUserid(qdTopFile.getUserid());
                bcTopFile.setSubtopid(qdTopFile.getSubtopid());
                bcTopFile.setProblemid(qdTopFile.getProblemid());
                bcTopFile.setClassid(qdTopFile.getClassid());
                bcTopFile.setFilename(fileName);
                bcTopFile.setFilepath(group);
                bcTopFile.setSimhash(msgSimHash);
                bcTopFile.setCheckmark(checkmark);
                bcTopFile.setSimilarity(similarity);
                topFileService.insertTopFile(bcTopFile);
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("code", code);
            ajax.put("msg", msg);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 下载文件地址
     */
    @GetMapping("/downLoad")
    public AjaxResult downLoad(TopFile qdTopFile) throws Exception {
        TopFile topFile = topFileService.selectTopFileById(qdTopFile.getId());
        ServiceImpl seaFile = new ServiceImpl();
        String path = topFile.getFilepath() + "/" + topFile.getFilename();
        String url = seaFile.GetDownLink(path);
        return AjaxResult.success(url);
    }

    /**
     * 打包下载地址
     */
    @GetMapping("/downLoadAll")
    public AjaxResult downLoadAll(TopFile qdTopFile) throws Exception {

        String url = "打包下载地址";
        return AjaxResult.success(url);
    }

    /**
     * SimHash查重
     */
    @PostMapping("/check")
    public AjaxResult uploadFile(MultipartFile file) throws Exception {
        // TODO: 2022/8/21 前端传递用户id、测验id、题目id
        Long userid = (long) 1;
        Integer subtopid = 1;
        Integer problemid = 1;
        try {
            // 获取文件simhash值
            String msgSimHash = WordUtil.getSimHash(file);
            // 查询所属分组的所有文件SimHash值
            TopFile topFile = new TopFile();
            String checkmark = subtopid.toString() + problemid.toString();// 查重标志=测验id+题目id
            topFile.setCheckmark(checkmark);
            List<TopFile> list = topFileService.selectTopFileList(topFile);
            //最大相似度
            double similarity = 0;
            for (TopFile tF : list) {
                if (similarity < HammingUtil.getSimilarity(msgSimHash, tF.getSimhash())) {
                    similarity = HammingUtil.getSimilarity(msgSimHash, tF.getSimhash());
                }
            }
            // 相似度处理
            similarity = (double) Math.round(similarity * 10000) / 100;
            // 查重信息
            String code = "";// 20220为通过，20221为未通过。
            String msg = "";
            if (similarity > 70) {
                code = "20221";
                msg = "未通过查重，相似度为：" + similarity + "%,大于70%";
            } else {
                code = "20220";
                msg = "恭喜你，已通过查重，相似度为：" + similarity + "%,小于70%";
                // 本地保存文件
                String group = subtopid.toString() + "/" + problemid.toString();
                // 保存文件
                WordUtil.saveFile(file, group);
                // 文件信息存入数据库
                TopFile bcTopFile = new TopFile();
                bcTopFile.setUserid(userid);
                bcTopFile.setSubtopid(subtopid);
                bcTopFile.setProblemid(problemid);
                bcTopFile.setFilename(file.getOriginalFilename());
                bcTopFile.setFilepath(group);
                bcTopFile.setSimhash(msgSimHash);
                bcTopFile.setCheckmark(checkmark);
                bcTopFile.setSimilarity(similarity);
                topFileService.insertTopFile(bcTopFile);
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("code", code);
            ajax.put("msg", msg);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }


    /**
     * 查询文件查重列表
     */
    @PreAuthorize("@ss.hasPermi('simhash:topFile:list')")
    @GetMapping("/list")
    public TableDataInfo list(TopFile topFile) {
        startPage();
        List<TopFile> list = topFileService.selectTopFileList(topFile);
        return getDataTable(list);
    }

    /**
     * 导出文件查重列表
     */
    @PreAuthorize("@ss.hasPermi('simhash:topFile:export')")
    @Log(title = "文件查重", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TopFile topFile) {
        List<TopFile> list = topFileService.selectTopFileList(topFile);
        ExcelUtil<TopFile> util = new ExcelUtil<TopFile>(TopFile.class);
        util.exportExcel(response, list, "文件查重数据");
    }

    /**
     * 获取文件查重详细信息
     */
    @PreAuthorize("@ss.hasPermi('simhash:topFile:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(topFileService.selectTopFileById(id));
    }

//    /**
//     * 获取文件查重详细信息
//     */
//    @PostMapping(value = "look/{problemId}")
//    public AjaxResult look(@PathVariable("problemId") Integer problemId) {
//        return AjaxResult.success(topFileService.selectTopFileByproblemId(problemId));
//    }
    @RequestMapping(value = "look/{problemId}", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public List<TopFile> query(@PathVariable("problemId") int problemId) {
        startPage();
        return topFileService.query(problemId);
    }
    @RequestMapping(value = "looked/{problemId}", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public List<TopFile> query1(@PathVariable("problemId") int problemId) {
        startPage();
        return topFileService.query1(problemId);
    }

    @RequestMapping(value = "queryById/{id}", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public TopFile queryById(@PathVariable("id") int id) {
        startPage();
        return topFileService.queryById(id);
    }

    /**
     * 新增文件查重
     */
    @PreAuthorize("@ss.hasPermi('simhash:topFile:add')")
    @Log(title = "文件查重", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TopFile topFile) {
        return toAjax(topFileService.insertTopFile(topFile));
    }

    /**
     * 修改文件查重
     */
    @PreAuthorize("@ss.hasPermi('simhash:topFile:edit')")
    @Log(title = "文件查重", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TopFile topFile) {
        return toAjax(topFileService.updateTopFile(topFile));
    }

    /**
     * 删除文件查重
     */
    @PreAuthorize("@ss.hasPermi('simhash:topFile:remove')")
    @Log(title = "文件查重", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(topFileService.deleteTopFileByIds(ids));
    }

    /**
     * 修改作业
     */
    @RequestMapping(value = "/update", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('teacher,admin,student')")
    public AjaxResult update(@RequestBody TopFile topFile) {
        if (topFileService.update(topFile) == 0) {
            return AjaxResult.error("修改成绩失败");
        }
        return AjaxResult.success("修改成绩成功");
    }
    /**
     * 插入时修改作业
     */
    @RequestMapping(value = "/updateIn", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public AjaxResult updateIn(@RequestBody TopFile topFile) {
        if (topFileService.updateIn(topFile) == 0) {
            return AjaxResult.error("修改成绩失败");
        }
        return AjaxResult.success("修改成绩成功");
    }

    /**
     * 删除作业
     */
    @RequestMapping(value = "/delete/{id}", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('teacher,admin,student')")
    public AjaxResult delete(@PathVariable("id") int id) {
        if (topFileService.delete(id) == 0) {
            return AjaxResult.error("打回作业失败");
        }
        return AjaxResult.success("打回作业成功");
    }

//    @Autowired
//    private DocumentConverter converter;  //用于转换
//
//    @ResponseBody
//    @RequestMapping("testPreview")
//    public void toPdfFile(HttpServletResponse response) {
//        File file = new File("D:\\testMyDoc\\doc\\testJc.docx");//需要转换的文件
//        try {
//            File newFile = new File("D:/testMyDoc");//转换之后文件生成的地址
//            if (!newFile.exists()) {
//                newFile.mkdirs();
//            }
//            String savePath="D:/testMyDoc/"; //pdf文件生成保存的路径
//            String fileName="JCccc"+UUID.randomUUID().toString().replaceAll("-","").substring(0,6);
//            String fileType=".pdf"; //pdf文件后缀
//            String newFileMix=savePath+fileName+fileType;  //将这三个拼接起来,就是我们最后生成文件保存的完整访问路径了
//
//            //文件转化
//            converter.convert(file).to(new File(newFileMix)).execute();
//            //使用response,将pdf文件以流的方式发送的前端浏览器上
//            ServletOutputStream outputStream = response.getOutputStream();
//            InputStream in = new FileInputStream(new File(newFileMix));// 读取文件
//            int i = IOUtils.copy(in, outputStream);   // copy流数据,i为字节数
//            in.close();
//            outputStream.close();
//            System.out.println("流已关闭,可预览,该文件字节大小："+i);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    @GetMapping("/Download")
    public String onlineDownload(FileMessageVO fileMessageVO) throws UnsupportedEncodingException {
//        String commonfile = "/home/common_files/";
        String commonfile = "D:/testMyDoc/";
        // 获取HttpServletResponse
        HttpServletResponse response =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        String fileName = fileMessageVO.getFullfilename();// 文件名
        if (fileName != null) {
            // 设置文件路径
            File file = new File(commonfile + fileName);
            if (file.exists()) {
                // 设置HTTP响应头
                response.reset();
                try {
                    OutputStream os = response.getOutputStream();
                    // 读取文件
                    InputStream in = new FileInputStream(file);
                    // copy文件
                    IOUtils.copy(in, os);
                    in.close();
                    os.close();
                    return "下载成功";
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return "下载失败";
    }


    @RequestMapping(value = "/checkedd", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public Integer checkedd(@RequestBody TopFile topFile) {
        startPage();
        return topFileService.checkedd(topFile);
    }
    /**
     * 修改作业
     */
    @RequestMapping(value = "/checkmyself", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public AjaxResult checkmyself(@RequestBody TopFile topFile) {
        System.out.println(topFileService.checkmyself(topFile));
        if (topFileService.checkmyself(topFile) == 0) {
            return AjaxResult.success("未提交");
        }
        return AjaxResult.success("已提交");
    }


     //     * 学生查询作业试题提交结果
    @RequestMapping(value = "/queryByStudent", method = {RequestMethod.POST})
    @ResponseBody
    @PreAuthorize("@ss.hasAnyRoles('student,teacher,admin')")
    public List<TopFile> queryByStudent(@RequestBody TopFile topFile) {
        startPage();
        return topFileService.queryByStudent(topFile);

    }
    @Anonymous
    @RequestMapping(value = "/uploadfiles",method = {RequestMethod.POST})
    @ResponseBody
    public AjaxResult uploadFolder(@RequestParam MultipartFile[] folder) {

        return AjaxResult.success(topFileService.saveMultiFile("D:/file", folder));
    }
}

